/****************************************************************
 * * Product  :   HP Subscriber Network Application Policy
 * * Module   :   gr-manager
 * * Date: Apr 10, 2015
 * * Author: Chen Zhenhua
 * * (C) Copyright 2015, Hewlett-Packard Company, All Rights Reserved.
 * * This software is the proprietary information of HP, Inc.
 * * Use is subject to license terms.
 * ****************************************************************
 * * Description:
 * *    Get Deployment site status.
 * *
 ****************************************************************/
package com.hp.snap.gr.action.impl;

import java.io.File;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.StringReader;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.hp.snap.gr.exception.ActionException;
import com.hp.snap.gr.model.DeployStatus;
import com.hp.snap.gr.model.SessionServerStatus;
import com.hp.snap.gr.model.jaxb.ActionType;
import com.hp.snap.gr.model.jaxb.GeneralActionType;
import com.hp.snap.gr.model.jaxb.ParameterType;
import com.hp.snap.gr.utils.*;

/**
 * Get Deployment site status. The Deployment is local deployment site or remote deployment site. Which can be specified
 * in the action configuration parameter. Construct the DeployStatus object,which include DeployName, DeployRole, GR
 * Status, session server status and biz service status info. And then the DeployStatus object save to
 * actionPlanOutputs("REMOTE_DEPLOY_STATUS").
 * <p/>
 * <p/>
 * There are two parameters can be configured in the action: Shell and Remote.
 * <p/>
 * Shell: get session server status shell script. Remote: is remote or local session sever, optional value: true or
 * false.
 * <p/>
 * Action output: REMOTE_DEPLOY_STATUS: the deployment site status.
 * <p/>
 * <p/>
 * Version: 3.3 <br>
 * Author: Chen Zhenhua Date: Apr 10, 2015
 * <p/>
 * </P>
 **/
public class CheckDeploymentStatusActionHandler extends AbstractActionHandler {

    private final static String SS_STATUS_RESULT_PREFIX = "{\"results\"";
    private static Logger logger = LoggerFactory.getLogger(CheckDeploymentStatusActionHandler.class);

    @Override
    public void execute(ActionType action,
            Map<String, Object> actionPlanInputs,
            Map<String, Object> actionPlanOutputs) throws ActionException {

        GeneralActionType actionType = (GeneralActionType) action;
        List<ParameterType> parameterTypes = actionType.getParameter();
        Map<String, String> parameterMap = Utils.contructParamMap(parameterTypes);

        String shellscript = parameterMap.get("Shell");
        String kernelConfigPath = parameterMap.get("GLOBAL_KERNEL_CONFIG_NODE");
        if (logger.isDebugEnabled()) {
            logger.debug("The shell script is:{}", Utils.maskEIUMPasswd(shellscript));
        }
        boolean remote = parameterMap.get("Remote") != null ? Boolean.parseBoolean(parameterMap.get("Remote")) : false;
        String _grStatusFilePath = Constants.USER_HOME + File.separator + "GR";
        CmdResult result = new CmdResult();
        try {

            int rs = CmdUtils.runShellScript("ls -alt " + _grStatusFilePath, result, false);

            if (rs != 0) {
                logger.error("execute the getting session server status shell script failed!");
                throw new ActionException(
                        "execute the getting  session server status shell script failed!");
            }

        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            throw new ActionException(ex);
        }

        String ssStatusStr = "";
        try {
            LineNumberReader r = new LineNumberReader(new StringReader(
                    result.getStdout().toString()));
            for (String line = r.readLine(); line != null; line = r.readLine()) {
                if (line.startsWith(SS_STATUS_RESULT_PREFIX)) {
                    ssStatusStr = line;
                    break;
                }
            }
        } catch (IOException e) {
            throw new ActionException(
                    "handle the session server status result failed!",
                    e.getCause());

        }
        if (logger.isDebugEnabled()) {
            logger.debug("session server status json string is:{}", ssStatusStr);
        }

        DeployStatus deployStatus = JSONUtils.getDeployStatus(ssStatusStr, remote, kernelConfigPath);

        //checking node available and lost node, 0:OK, 1:WARN, 2:ERROR
        int checkResult = 0;
        Map<String, List<SessionServerStatus>> sessionServerStatusMap = deployStatus.getSessionServerStatusMap();
        if (!sessionServerStatusMap.isEmpty()) {
            for (String s : sessionServerStatusMap.keySet()) {
                List<SessionServerStatus> sessionServerStatuses = sessionServerStatusMap.get(s);
                if (!sessionServerStatuses.isEmpty()) {
                    for (SessionServerStatus sessionServerStatuse : sessionServerStatuses) {
                        if (!SessionServerStatus.ProcessStatus.RUNNING.equals(sessionServerStatuse
                                .getProcessStatus())) {
                            checkResult = 2;
                            break;
                        }
                    }
                } else {
                    checkResult = 2;
                }
            }
        } else {
            checkResult = 2;
        }
        // output to shell command
        Constants.CONSOLE.info("PROCESS_CHECK_OUTPUT:" + checkResult);

        actionPlanOutputs.put(Constants.REMOTE_DEPLOY_STATUS, deployStatus);
    }

}
